// board version 2.1, 20120605


////////////////////////////////
#include "commons.h"
#include "trials.h"
#include "zxLib.h"

#define versionInfo "zxx 20130819 v12"


_FOSC(CSW_FSCM_OFF & XT_PLL4);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & BORV20 & PWRT_64 & MCLR_EN);



unsigned char txtWelcomTop[] = {0x48, 0x61, 0x76, 0x65, 0x20, 0x61, 0x20, 0x47, 0x6f, 0x6f, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65}; //Have a Good Time
unsigned char txtWelcomBottom[] = {0x20, 0x20, 0x7a, 0x78, 0x78, 0x20, 0x20, 0x20, 0x32, 0x30, 0x31, 0x33, 0x30, 0x38, 0x30, 0x37};

int main(void) {
    // set portb to digital or AD port
    ADPCFG = 0xFFFF; // all PORTB = Digital; RB2 = analog
    SetupPorts();
    Init_PWM();
    Init_LCD();
    InitTMR2();
    InitTMR1();
    InitUART2();
    Nop();
    // welcome
    home_clr();
    LCDWriteString("Happy Train Mice");
    line_2();
    LCDWriteString(versionInfo);

    // debugging
    unsigned char StartText[] = {0x00, 0x01, 0x02, 0x03}; //    Odor B
    Puts_UART2((unsigned char*) &StartText[0], sizeof (StartText));

    DelayNmSecNew(1000);
    unsigned int n;
    //    unsigned int subN;
    while (1) {
        srand((unsigned) time(NULL));
        n = getFuncNumber(3, "Main Function ?");
        switch (n) {
            case 111:
                test_valve(water_sweet);
                break;
            case 112:
                test_valve(odor_A);
                break;
            case 113:
                test_valve(odor_B);
                break;
            case 114:
                auto_test_valve();
                break;
            case 115:
                test_BNC();
                break;
            case 131:
                AB_BA_Go(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 6.0, 7.0, 17.0, 20, 99);
                break;
            case 132:
                AB_BA_Go(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 8.0, 18.0, 20, 99);
                break;
            case 133:
                AA_BB_Go(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 8.0, 18.0, 20, 99);
                break;
            case 134:
                TwoOdorDelayMatchTask(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 6.0, 7.0, 17.0, 1, 20, 99);
                break;
            case 151:
                Go_noGo(odor_A, 2, odor_B, 3, 0.0, 1.0, 4, 1.0, 2.0, 6.0, 3, 20, 99);
                break;
            case 152:
                Go_noGo(odor_A, 2, odor_B, 3, 0.0, 1.0, 4, 2.0, 3.0, 7.0, 3, 20, 99);
                break;
            case 153:
                Go_noGo(odor_A, 2, odor_B, 3, 0.0, 1.0, 4, 2.0, 3.0, 7.0, 1, 20, 99);
                break;
            case 154:
                Go_noGo(odor_C, 2, odor_D, 3, 0.0, 1.0, 4, 1.0, 2.0, 6.0, 3, 20, 99);
                break;
            case 155:
                RandomGoNogo(odor_A, 2, odor_B, 3, 0.0, 1.0, 4, 1.0, 2.0, 6.0, 3, 20, 99);
                break;
            case 211:
                TwoOdorDelayMatchTask(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 1, 20, 99);
                break;
            case 212:
                TwoOdorDelayMatchTask(odor_A, 2, 0.0, 1.0, odor_B, 3, 9.0, 10.0, 4, 11.0, 11.5, 25.5, 1, 20, 99);
                break;
            case 213:
                TwoOdorDelayMatchTask(odor_A, 2, 0.0, 1.0, odor_B, 3, 17.0, 18.0, 4, 19.0, 19.5, 41.5, 1, 20, 99);
                break;
            case 214:
                TwoOdorDelayMatchTask(odor_A, 2, 0.0, 2.0, odor_B, 3, 6.0, 7.0, 4, 8.0, 8.5, 18.5, 1, 20, 99);
                break;
            case 215:
                TwoOdorDelayMatchTask(odor_A, 2, 0.0, 4.0, odor_B, 3, 8.0, 9.0, 4, 10.0, 10.5, 20.5, 1, 20, 99);
                break;
            case 221:
                TwoOdorDelayMatchTask(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 2, 20, 99);
                break;
            case 222:
                TwoOdorDelayMatchTaskWithTwoTriggerWithDistructor(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, odor_C, 7, 1.0, 5.0, 4, 7.0, 7.5, 17.5, 8, 0.0, 1.0, 8, 5.0, 6.0, 1, 20, 99);
                break;
            case 223:
                TwoOdorDelayMatchTaskWithTwoTriggerWithDistructor(odor_A, 2, 1.0, 5.0, odor_B, 3, 5.0, 6.0, odor_C, 7, 0.0, 1.0, 4, 7.0, 7.5, 17.5, 8, 0.0, 1.0, 8, 5.0, 6.0, 1, 20, 99);
                break;
            case 224:
                PseudoDNMSTasks(odor_A, odor_D, 2, 1.0, 5.0, odor_B, odor_E, 3, 5.0, 6.0, odor_C, 7, 0.0, 1.0, 4, 7.0, 7.5, 17.5, 8, 0.0, 1.0, 8, 5.0, 6.0, 5, 20, 99);
                break;
            case 225:
                PseudoDNMSTasks(odor_A, odor_D, 2, 1.0, 5.0, odor_B, odor_E, 3, 5.0, 6.0, odor_C, 7, 0.0, 5.0, 4, 7.0, 7.5, 17.5, 8, 0.0, 1.0, 8, 5.0, 6.0, 5, 20, 99);
                break;
            case 231:
                TwoOdorDelayMatchTask(odor_A, 2, 0.0, 5.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 1, 20, 99);
                break;
            case 233:
                air_Go_Nogo(2, 2, 20, 1.0, 50, 10, 0.1);
                break;
            case 234:
                auto_AB_BA_Go_AA_BB_Nogo_Ran2(2, 5, 40, 1.0, 50, 2, 0.0);
                break;
            case 311:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 5, 1.0, 5.0, 1, 20, 99);
                break;
            case 312:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 5, 0.0, 1.0, 1, 20, 99);
                break;
            case 313:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 5, 5.0, 6.0, 1, 20, 99);
                break;
            case 314:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 5, 7.5, 17.5, 1, 20, 99);
                break;
            case 315:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 5, 6.0, 7.0, 1, 20, 99);
                break;
            case 321:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 9.0, 10.0, 4, 11.0, 11.5, 25.5, 5, 1.0, 9.0, 1, 20, 99);
                break;
            case 322:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 9.0, 10.0, 4, 11.0, 11.5, 25.5, 5, 0.0, 1.0, 1, 20, 99);
                break;
            case 323:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 9.0, 10.0, 4, 11.0, 11.5, 25.5, 5, 9.0, 10.0, 1, 20, 99);
                break;
            case 324:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 9.0, 10.0, 4, 11.0, 11.5, 25.5, 5, 11.5, 25.5, 1, 20, 99);
                break;
            case 325:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 9.0, 10.0, 4, 11.0, 11.5, 25.5, 5, 10.0, 11.0, 1, 20, 99);
                break;
            case 331:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 5, 1.5, 2.5, 1, 20, 99);
                break;
            case 332:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 9.0, 10.0, 4, 11.0, 11.5, 25.5, 5, 2.0, 4.0, 1, 20, 99);
                break;
            case 333:
                TwoOdorDelayMatchTaskWithTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 17.0, 18.0, 4, 19.0, 19.5, 41.5, 5, 3.0, 7.0, 1, 20, 99);
                break;
            case 351:
                n = getFuncNumber(1, "AGo1 BGo2 Rand3");
                zxGo_nogo_autoSwitch(n, 20, odor_A, odor_B, 1, 1, 0.5, 4, 0, 0, 1, 0, 0);
                break;
            case 352:
                test_odor_Advanced(500);
                break;

            case 353:
                n = getFuncNumber(1, "oLen S1=1 S2=0.5");
                setOdorLength(n == 2 ? 0.5 : 1.0);
                zxDNMSSessions(4, 10, 20, 0.5, 1.0, 100, 40);
                break;
            case 354:
                n = getFuncNumber(1, "oLen S1=1 S2=0.5");
                setOdorLength(n == 2 ? 0.5 : 1.0);
                zxDNMSLaserSessions(4, 10, 20, 0.5, 50, 15, 1.0, delayBeforeLaserDuration, entireLaserDuration);
                break;
            case 411:
                TwoOdorDelayMatchTaskWithTwoTrigger(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 5, 0.0, 1.0, 5, 5.0, 6.0, 1, 20, 99);
                break;
            case 511:
                TwoOdorVaryingTasks(odor_A, 2, odor_B, 3, 0.0, 1.0, 5.0, 6.0, 0.0, 1.0, 9.0, 10.0, 0.0, 1.0, 17.0, 18.0, 2, 2, 1, 4, 7.0, 7.5, 11.0, 11.5, 19.0, 19.5, 17.5, 25.5, 41.5, 6, 17.0, 17.5, 6, 25.0, 25.5, 6, 41.0, 41.5, 1, 1, 1, 20, 99);
                break;
            case 512:
                TwoOdorVaryingTasks(odor_A, 2, odor_B, 3, 0.0, 1.0, 5.0, 6.0, 0.0, 2.0, 6.0, 7.0, 0.0, 4.0, 8.0, 9.0, 2, 2, 1, 4, 7.0, 7.5, 8.0, 8.5, 10.0, 10.5, 17.5, 18.5, 20.5, 6, 17.0, 17.5, 6, 18.0, 18.5, 6, 20.0, 20.5, 1, 1, 1, 20, 99);
                break;
            case 513:
                TwoOdorVaryingTasks(odor_A, 2, odor_B, 3, 0.0, 1.0, 5.0, 6.0, 0.0, 1.0, 5.0, 6.0, 0.0, 1.0, 5.0, 6.0, 2, 2, 0, 4, 7.0, 7.5, 7.0, 7.5, 7.0, 7.5, 17.5, 17.5, 17.5, 5, 1.5, 2.5, 6, 17.0, 17.5, 6, 17.0, 17.5, 1, 1, 1, 20, 99);
                break;
            case 514:
                AutoTwoRuleBlockTask(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 6, 17.0, 17.5, 6, 17.0, 17.5, 1, 2, 20, 99);
                break;
            case 515:
                AutoTwoRuleBlockTask(odor_A, 2, 0.0, 1.0, odor_B, 3, 5.0, 6.0, 4, 7.0, 7.5, 17.5, 6, 17.0, 17.5, 6, 17.0, 17.5, 2, 1, 20, 99);
                break;
            case 521:
                EightOdorGo_noGo();
                break;
            case 522:
                AutoTwoRuleGoNogoTask(odor_A, 2, odor_B, 3, 0.0, 1.0, 4, 2.0, 2.5, 6.5, 5, 1.7, 2.0, 6, 6.0, 6.4, 3, 4, 20, 99);
                break;
            case 523:
                AutoTwoRuleGoNogoTask(odor_A, 2, odor_B, 3, 0.0, 1.0, 4, 2.0, 2.5, 6.5, 5, 1.7, 2.0, 6, 6.0, 6.4, 4, 3, 20, 99);
        }
    }
    return 0;
}
